HTTP vs WebSocket:两种通信模型的根本差异
理解 WebSocket 之前,需要先搞清楚它为什么要存在。传统的 HTTP 协议采用的是"请求-响应"模型:客户端发送请求,服务端返回响应,一次交互就结束了。如果客户端需要获取服务端的最新状态,只能不断轮询——比如每隔 5 秒用 Ajax 发一次请求,问服务端"数据变了没有"。这种做法有三个致命问题:第一,无法实时感知状态变化,轮询间隔内发生的事件客户端完全不知道;第二,效率极低,即使服务端状态没变也要处理请求;第三,浪费带宽和服务器资源,每次轮询都要携带完整的 HTTP 头部。
WebSocket 协议在 HTML5 中被正式定义,它建立在 TCP 连接之上,通过一次 HTTP 握手升级(Upgrade)建立长连接,之后客户端和服务端可以在同一条通道上双向发送消息。握手成功后,通信不再遵循 HTTP 的请求-响应模式,而是类似一条保持打开的双向管道。当没有消息传输时,整个信道处于空闲状态,不会占用带宽,也不会消耗服务器 CPU 去查询数据库。这就是 WebSocket 设计的初衷——为实时通信场景提供一种高效、低延迟的传输协议。
WebSocket 协议的核心特性
WebSocket 位于 OSI 模型的应用层,与 HTTP 同层,但有几个本质区别:
| 特性 | HTTP | WebSocket |
|---|---|---|
| 通信模式 | 请求-响应(单向) | 全双工(双向) |
| 连接生命周期 | 短连接(HTTP/1.1 可 Keep-Alive) | 长连接 |
| 状态 | 无状态 | 有状态(保持连接) |
| 服务端推送 | 不支持(需轮询/SSE) | 原生支持 |
| 协议标识 | http:// / https:// | ws:// / wss:// |
| 同源限制 | 受同源策略约束 | 无同源限制 |
| 数据格式 | 文本为主(HTTP/2 支持二进制) | 文本和二进制均原生支持 |
握手过程的关键在于 HTTP 的 Upgrade 头部。客户端发送一个特殊的 HTTP 请求:
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13
http
服务端如果支持 WebSocket,会返回 101 Switching Protocols 状态码,表示协议升级成功,此后这个 TCP 连接就变成了 WebSocket 连接:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
http
浏览器兼容性
截至 2026 年,WebSocket 已经获得了所有主流浏览器的支持。根据 Can I Use 的数据,全球浏览器对 WebSocket 的支持率超过 98%。IE 浏览器从 IE10 开始支持 WebSocket,如果项目需要兼容 IE9 及以下版本,就需要使用 Socket.IO 等库做降级处理(回退到 HTTP 长轮询)。在实际开发中,除非面对特殊的内网环境或老旧设备,否则基本不需要考虑兼容性问题。
WebSocket 的典型应用场景
WebSocket 最适合那些需要"服务端主动向客户端推送数据"的实时场景:
即时通讯与社交互动:聊天室、私信、点赞通知、好友上下线状态。微信网页版的早期版本就是基于 WebSocket 实现实时消息推送的。
直播与弹幕:斗鱼、B站等直播平台的弹幕系统是 WebSocket 的经典应用。弹幕需要低延迟地广播给所有在线观众,同时还要混合历史消息的拉取逻辑。
协同编辑:Google Docs、腾讯文档、飞书文档等多人在同一文档上实时编辑,光标位置同步、文本变更同步都需要 WebSocket 的双向通信能力。
在线游戏:多人联机游戏的位置同步、动作广播。例如你看到的王者荣耀、原神等游戏的 Web 版联机功能。
实时数据监控:服务器性能监控面板(如 Grafana 实时数据流)、股票行情推送、IoT 设备状态上报等。
地理位置服务:外卖骑手实时位置展示、打车应用的车辆位置更新。
理解这些场景有助于判断何时该用 WebSocket,何时用传统 HTTP 请求就够了。核心判断依据是:服务端是否需要主动推送数据,以及实时性要求有多高。
关于连接资源的误区
很多初学者会担心 WebSocket 长连接会不会浪费服务器资源。实际上,WebSocket 的设计本身就是为了适应长连接场景。握手完成后,连接处于空闲状态时不会执行任何业务逻辑,也不会查询数据库,因此不会造成系统资源的浪费。网络资源方面,空闲的 WebSocket 连接不传输任何数据,自然也不会占用带宽。
真正需要注意的资源消耗在于 TCP 层面——每建立一条 WebSocket 连接,操作系统都会分配一个文件描述符(File Descriptor)和一个随机端口。当并发连接数很高时,这会成为瓶颈。这也是为什么后续课程会讲到使用单例模式和 SharedWorker 来减少不必要的连接数。
↑